package com.kmzx.one.project.config.web;

import com.kmzx.one.common.annotation.ApiAuth;
import com.kmzx.one.common.constants.Constants;
import com.kmzx.one.project.entity.UserLogger;
import com.kmzx.one.project.mapper.CustomerMapper;
import com.kmzx.one.project.mapper.UserRankMapper;
import com.kmzx.one.project.others.dso.UserRankDso;
import com.kmzx.one.project.service.UserLogService;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.List;

/**
 * @Project one
 * @Author: carol
 * @Date: 2020/5/21-17:19
 */
@Component
public class UserInterceptorAdapter extends HandlerInterceptorAdapter {


    @Autowired
    UserLogService userLogService;

    @Autowired
    StringRedisTemplate stringRedisTemplate;

    @Autowired
    UserRankMapper userRankMapper;

    @Autowired
    RedisTemplate<String, Object> objectRedisTemplate;

    @Autowired
    CustomerMapper customerMapper;


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        String method = request.getMethod();
        if (method.equals(RequestMethod.OPTIONS.name())) {
            setHeader(request, response);
            return true;
        }


        String requestURI = request.getRequestURI();
        String contentType = request.getContentType();
//        ServletInputStream in = null;
//        if("POST".equals(method)){
//            ServletInputStream inputStream = request.getInputStream();
//            in = inputStream;
//            String postData = IOUtils.toString(in, "UTF-8");
//            if ("application/json".equals(contentType)) {
//                JSONObject jsonObject = JSON.parseObject(postData);
//                if (requestURI.contains("gen2")) {
//                    JSONObject once = jsonObject.getJSONObject("once");
//                    String id = once.getString("userId");
//                    userId = id;
//                }
//            }
//        }
//        if ("POST".equals(method)) {
//            BodyRequestWrapper requestWrapper = new BodyRequestWrapper(request);
//            ServletInputStream stream = requestWrapper.getInputStream();
//            String postData = IOUtils.toString(stream, "UTF-8");
//            if ("application/json".equals(contentType)) {
//                JSONObject jsonObject = JSON.parseObject(postData);
//                if (requestURI.contains("gen2")) {
//                    JSONObject once = jsonObject.getJSONObject("once");
//                    String id = once.getString("userId");
//                    userId = id;
//                }
//            }
//        } else {
//        }
        String address = getIpAddress(request);
        String agent = request.getHeader("User-Agent");
        //记录客户端IP
        request.setAttribute("clientIP", address);

        String tokenUser = request.getHeader("tokenUser");


        UserLogger userLogger = new UserLogger();
        userLogger.setAddress(address).setMethod(method).setRequestUrl(requestURI)
                .setUserId(tokenUser).setUserAgent(agent);
        String goodsId = request.getParameter("goodsId");
        String productId = request.getParameter("productId");
        if (goodsId != null && goodsId != "") {
            userLogger.setRequestUrl(requestURI.concat(goodsId));
        } else if (productId != null && productId != "") {
            userLogger.setRequestUrl(requestURI.concat(productId));
        }


        String chUnionId = request.getParameter("chUnionId");

        if(chUnionId!=null&& "".equals(chUnionId)){
            userLogger.setUnionId(chUnionId);
        }else {
            userLogger.setUnionId(null);
        }

        if (handler instanceof HandlerMethod) {
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            Method javaMethod = handlerMethod.getMethod();

            boolean needAuth = javaMethod.isAnnotationPresent(ApiOperation.class);

            if (needAuth) {
                ApiOperation apiOperation = javaMethod.getAnnotation(ApiOperation.class);
                String value = apiOperation.value();
                int position = apiOperation.position();
                userLogger.setPosition(position);
                userLogger.setMethod(value);
            }

            boolean apiAuth = javaMethod.isAnnotationPresent(ApiAuth.class);
            if (apiAuth) {


                if (tokenUser != null && !"".equals(tokenUser) && !"null".equals(tokenUser)) {
                    String s = stringRedisTemplate.opsForValue().get(Constants.user_rank_prefix + ":" + tokenUser);
                    if (s != null) {
                        request.setAttribute("level", s);
                    } else {
                        stringRedisTemplate.opsForValue().set(Constants.user_rank_prefix + ":" + tokenUser, "");
//                        UserRank userRank = userRankMapper.selectUserRankByUserId(tokenUser);
//                        request.setAttribute("level", userRank.getRankId());
                    }


                } else {

                    String s = stringRedisTemplate.opsForValue().get(Constants.user_rank_prefix + ":no");
                    if (s != null) {
                        request.setAttribute("level", s);
                    } else {
                        Object o = objectRedisTemplate.opsForValue().get(Constants.all_rank_prefix);
                        if (o != null) {
                            List<UserRankDso> dsos = (List<UserRankDso>) o;

                            String rankId = dsos.get(0).getRankId();
                            stringRedisTemplate.opsForValue().set(Constants.user_rank_prefix + ":no", rankId);
                        } else {
                            List<UserRankDso> dsos = userRankMapper.selectAllRankTabs();
                            objectRedisTemplate.opsForValue().set(Constants.all_rank_prefix, dsos);

                            String rankId = dsos.get(0).getRankId();
                            stringRedisTemplate.opsForValue().set(Constants.user_rank_prefix + ":no", rankId);
                        }
                    }
                }
            }
        }

        userLogService.asyncInsertLoggerUser(userLogger);
        return true;
    }

    /**
     * 为response设置header，实现跨域
     */
    private void setHeader(HttpServletRequest request, HttpServletResponse response) {
        //跨域的header设置
        response.setHeader("Access-control-Allow-Origin", request.getHeader("Origin"));
        response.setHeader("Access-Control-Allow-Methods", request.getMethod());
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Allow-Headers", request.getHeader("Access-Control-Request-Headers"));
        //防止乱码，适用于传输JSON数据
        response.setHeader("Content-Type", "application/json;charset=UTF-8");
    }


    public String getIpAddress(HttpServletRequest request) {
        String ipAddress = null;
        try {
            ipAddress = request.getHeader("x-forwarded-for");
            if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
                ipAddress = request.getHeader("Proxy-Client-IP");
            }
            if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
                ipAddress = request.getHeader("WL-Proxy-Client-IP");
            }
            if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
                ipAddress = request.getRemoteAddr();
                if (ipAddress.equals("127.0.0.1")) {
                    // 根据网卡取本机配置的IP
                    InetAddress inet = null;
                    try {
                        inet = InetAddress.getLocalHost();
                    } catch (UnknownHostException e) {
                        e.printStackTrace();
                    }
                    ipAddress = inet.getHostAddress();
                }
            }
            // 对于通过多个代理的情况，第一个IP为客户端真实IP,多个IP按照','分割
            if (ipAddress != null && ipAddress.length() > 15) { // "***.***.***.***".length()
                // = 15
                if (ipAddress.indexOf(",") > 0) {
                    ipAddress = ipAddress.substring(0, ipAddress.indexOf(","));
                }
            }
        } catch (Exception e) {
            ipAddress = "";
        }
        return ipAddress;
    }

}
